- Для выполнения заданий обязательно ознакомьтесь с инструкцией по экономии облачных ресурсов. Это нужно, чтобы не расходовать средства, полученные в результате использования промокода.
- Своё решение к задачам оформите в вашем GitHub репозитории.
- В личном кабинете отправьте на проверку ссылку на .md-файл в вашем репозитории.
- Сопроводите ответ необходимыми скриншотами.
Примечание: Ознакомьтесь со схемой виртуального стенда по ссылке
- Сделайте в своем github пространстве fork репозитория
https://github.com/netology-code/shvirtd-example-python/blob/main/README.md
. - Создайте файл с именем
Dockerfile.python
для сборки данного проекта(для 3 задания изучите https://docs.docker.com/compose/compose-file/build/ ). Используйте базовый образpython:3.9-slim
. Протестируйте корректность сборки. Не забудьте dockerignore.
- создал .dockerignore но, пока в него писать нечего, т.к. я не копирую папками ничего в докер образ (копирую только то что явно нужно).
- создаю образ докера:
FROM python:3.9-slim
ENV DB_HOST=172.20.0.10
ENV DB_TABLE=requests
ENV DB_USER=root
ENV DB_NAME=db1
ENV DB_PASSWORD=12345
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY main.py ./
CMD ["python", "main.py"]
docker build -f Dockerfile.python -t mydoc .
- (Необязательная часть, *) Изучите инструкцию в проекте и запустите web-приложение без использования docker в venv. (Mysql БД можно запустить в docker run).
Вот что сделал: Создал файл компоса:
version: '3.7'
# Use root/example as user/password credentials
services:
mysql:
image: mysql
# NOTE: use of "mysql_native_password" is not recommended: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password
# (this is just an example, not intended to be a production configuration)
command: --default-authentication-plugin=mysql_native_password
restart: always
#env_file: .env
environment:
MYSQL_ROOT_PASSWORD: 12345
MYSQL_USER: user
MYSQL_PASSWORD: 12345
ports:
- 3306:3306
volumes:
- ./docker_volumes/mysql:/var/lib/mysql
networks:
docker-net:
ipv4_address: 172.20.0.10
networks:
docker-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
apt install mariadb-client-core-10.6
mysql -p -h 172.20.0.10 -P 3306 -u root
MySQL [(none)]> create database db1;
Запустил - поднял докер контейнер с MYSQL через DBeaver создал db1 и запустил:
export DB_HOST=172.20.0.10 \
export DB_USER=root \
export DB_PASSWORD=12345 \
export DB_NAME=db1
apt install python3.10-venv
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
python main.py
Сделал запрос на внешний адрес и 5000 порт:
Но, последующие запросы уже не шли. Вот что было в выводе:
С пользователем user не заработало, а спользователем root заработало, тк не хватает прав для user - нужно особо выдавать, не стал это делать, а использовал root_
- (Необязательная часть, *) По образцу предоставленного python кода внесите в него исправление для управления названием используемой таблицы через ENV переменную.
правки:
db_table=os.environ.get('DB_TABLE')
...
# SQL-запрос для создания таблицы в БД
create_table_query = f"""
CREATE TABLE IF NOT EXISTS {db_database}.{db_table} (
id INT AUTO_INCREMENT PRIMARY KEY,
request_date DATETIME,
request_ip VARCHAR(255)
)
"""
...
query = f"""INSERT INTO {db_table} (request_date, request_ip) VALUES (%s, %s)"""
и переменные теперь так:
export DB_HOST=172.20.0.10 \
export DB_USER=root \
export DB_PASSWORD=12345 \
export DB_NAME=db1 \
export DB_TABLE=requests \
Остальное без изменений.
Заработало:
интересно что значит конструкция f"""...""" и чем отличатеся от "..." ?
!!! В процессе последующего выполнения ДЗ НЕ изменяйте содержимое файлов в fork-репозитории! Ваша задача ДОБАВИТЬ 5 файлов: Dockerfile.python
, compose.yaml
, .gitignore
, .dockerignore
,bash-скрипт
. Если вам понадобилось внести иные изменения в проект - вы что-то делаете неверно!
- Создайте в yandex cloud container registry с именем "test" с помощью "yc tool" . Инструкция
- Настройте аутентификацию вашего локального docker в yandex container registry.
- Соберите и залейте в него образ с python приложением из задания №1.
- Просканируйте образ на уязвимости.
- В качестве ответа приложите отчет сканирования.
docker build -t myapp -f Dockerfile.python .
docker compose up -d
docker logs 5f321a9917f9
apt install mysql-client-core-8.0
mysql -p -h 172.20.0.10 -P 3306 -u root --password=12345 --init-command="create database db1;"
mysql> show databases;
docker compose up -d
root@dp:~/shvirtd-example-python# curl -sSL https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
yc container registry create --name test
yc container registry configure-docker
docker tag myapp cr.yandex/crp5gbscd8f2re1ga8ip/myapp:latest
docker push cr.yandex/crp5gbscd8f2re1ga8ip/myapp
yc container image list --repository-name=crp5gbscd8f2re1ga8ip/myapp
yc container image scan crprcak0gm7fn41j9ik2
yc container image list-vulnerabilities --scan-result-id=chekusor1mibehitcpu6
Критическая уязвимость: https://avd.aquasec.com/nvd/2023/cve-2023-45853/
Инструкция: https://yandex.cloud/ru/docs/container-registry/operations/scanning-docker-image
-
Изучите файл "proxy.yaml"
-
Создайте в репозитории с проектом файл
compose.yaml
. С помощью директивы "include" подключите к нему файл "proxy.yaml". файл уже создал ранее, тут теперь его редактирую -
Опишите в файле
compose.yaml
следующие сервисы:
web
. Образ приложения должен ИЛИ собираться при запуске compose из файлаDockerfile.python
ИЛИ скачиваться из yandex cloud container registry(из задание №2 со *). Контейнер должен работать в bridge-сети с названиемbackend
и иметь фиксированный ipv4-адрес172.20.0.5
. Сервис должен всегда перезапускаться в случае ошибок. Передайте необходимые ENV-переменные для подключения к Mysql базе данных по сетевому имени сервисаweb
код сервиа:
web:
image: myapp
restart: on-failure
environment:
- DB_HOST=172.20.0.10
- DB_TABLE=requests
- DB_USER=root
- DB_NAME=db1
- DB_PASSWORD=12345
depends_on:
- db
ports:
- 5000:5000
networks:
backend:
ipv4_address: 172.20.0.5
db
. image=mysql:8. Контейнер должен работать в bridge-сети с названиемbackend
и иметь фиксированный ipv4-адрес172.20.0.10
. Явно перезапуск сервиса в случае ошибок. Передайте необходимые ENV-переменные для создания: пароля root пользователя, создания базы данных, пользователя и пароля для web-приложения.Обязательно используйте уже существующий .env file для назначения секретных ENV-переменных!
код сервиса:
db:
image: mysql:8
# NOTE: use of "mysql_native_password" is not recommended: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password
# (this is just an example, not intended to be a production configuration)
command: --default-authentication-plugin=mysql_native_password
restart: on-failure
#env_file: .env
environment:
MYSQL_ROOT_PASSWORD: 12345
MYSQL_USER: user
MYSQL_PASSWORD: 12345
ports:
- 3306:3306
volumes:
- ./docker_volumes/mysql:/var/lib/mysql
networks:
backend:
ipv4_address: 172.20.0.10
- Запустите проект локально с помощью docker compose , добейтесь его стабильной работы: команда
curl -L http://127.0.0.1:8090
должна возвращать в качестве ответа время и локальный IP-адрес. Если сервисы не стартуют воспользуйтесь командами:docker ps -a
иdocker logs <container_name>
- Подключитесь к БД mysql с помощью команды
docker exec <имя_контейнера> mysql -uroot -p<пароль root-пользователя>
. Введите последовательно команды (не забываем в конце символ ; ):show databases; use <имя вашей базы данных(по-умолчанию example)>; show tables; SELECT * from requests LIMIT 10;
.
выполнил не в контейнере а с хостовой машины - так как все равно арнее поставил Mysql
mysql> SELECT * from requests order by id desc limit 20;
- Остановите проект. В качестве ответа приложите скриншот sql-запроса.
не понял, что значит "остановить проект"? остановить все контейнеры? тогда как можно получить результат запроса если контейнер с БД остановлен?
docker compose down
Подключиться к БД уже не получается.
- Запустите в Yandex Cloud ВМ (вам хватит 2 Гб Ram).
уже сразу так и сделал
- Подключитесь к Вм по ssh и установите docker.
докер установлен при создании ВМ через терраформ:
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y ca-certificates curl gnupg",
"sudo install -m 0755 -d /etc/apt/keyrings",
"curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg",
"sudo chmod a+r /etc/apt/keyrings/docker.gpg",
"echo \"deb [arch=\"$(dpkg --print-architecture)\" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \"$(. /etc/os-release && echo \"$VERSION_CODENAME\")\" stable\" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null",
"sudo apt-get update",
"sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin",
"sudo chmod +x /root/proxy.yaml",
"apt install -y mariadb-client-core-10.6 ",
"git clone https://github.com/DmitryIll/shvirtd-example-python.git"
]
}
- Напишите bash-скрипт, который скачает ваш fork-репозиторий в каталог /opt и запустит проект целиком.
я скачал в дирректорию root. Но, можно и opt - не принципиально.
cd /opt
git clone https://github.com/DmitryIll/shvirtd-example-python.git
Опять пришлось новую БД создать:
- Зайдите на сайт проверки http подключений, например(или аналогичный):
https://check-host.net/check-http
и запустите проверку вашего сервисаhttp://<внешний_IP-адрес_вашей_ВМ>:8090
. Таким образом трафик будет направлен в ingress-proxy.
- (Необязательная часть) Дополнительно настройте remote ssh context к вашему серверу. Отобразите список контекстов и результат удаленного выполнения
docker ps -a
- В качестве ответа повторите sql-запрос и приложите скриншот с данного сервера, bash-скрипт и ссылку на fork-репозиторий.
https://github.com/DmitryIll/shvirtd-example-python.git
Скрипты команд, наработанные когда вручную запускал (в формате заметок):
docker network create --driver=bridge net1
#Запускаем контейнер с Mysql в сети 'wordpress'. Благо вольюм сздается автоматически!
docker run -d --network='net1' --hostname='mysql' -v 'db_data:/var/lib/mysql' -e 'MYSQL_ROOT_PASSWORD=12345' -e 'MYSQL_DATABASE=db1' -e 'MYSQL_USER=user' -e 'MYSQL_PASSWORD=12345' mariadb:10.6.4-focal --default-authentication-plugin='mysql_native_password'
export DB_HOST=172.20.0.10 \
export DB_USER=root \
export DB_PASSWORD=12345 \
export DB_NAME=db1 \
export DB_TABLE=requests \
db_host=os.environ.get('DB_HOST')
db_user=os.environ.get('DB_USER')
db_password=os.environ.get('DB_PASSWORD')
db_database=os.environ.get('DB_NAME')
apt install mysql-client-core-8.0
mysql --password=mypassword --user=me --host=etc
mysql -p -h 172.20.0.10 -P 3306 -u root --password=12345 --init-command="create database db1;"
mysql show databases;
mysql -p -h 172.20.0.10 -P 3306 -u root --password=12345
mysql> select * from db1.requests;
- Напишите и задеплойте на вашу облачную ВМ bash скрипт, который произведет резервное копирование БД mysql в директорию "/opt/backup" с помощью запуска в сети "backend" контейнера из образа
schnitzler/mysqldump
при помощиdocker run ...
команды. Подсказка: "документация образа." - Протестируйте ручной запуск
- Настройте выполнение скрипта раз в 1 минуту через cron, crontab или systemctl timer. Придумайте способ не светить логин/пароль в git!!
- Предоставьте скрипт, cron-task и скриншот с несколькими резервными копиями в "/opt/backup"
Скачайте docker образ hashicorp/terraform:latest
и скопируйте бинарный файл /bin/terraform
на свою локальную машину, используя dive и docker save.
Предоставьте скриншоты действий .
docker pull hashicorp/terraform:latest
Нашел в каком слое появился файл терраформа:
слой sha256:b22c6fe345f979d4956c9570f757a0d13f1d7abf0b26121f3adfed2cf580c055
Выгружаю образ:
docker save hashicorp/terraform -o image.tar
Нашел нужный слой и распаковал его:
Добейтесь аналогичного результата, используя docker cp.
Предоставьте скриншоты действий .
Запускаю контейнер пусть даже с ошибкой:
смотрю контейнеры:
Далее копирую все из bin
или можно точнее сразу:
Предложите способ извлечь файл из контейнера, используя только команду docker build и любой Dockerfile.
Предоставьте скриншоты действий .
Запустите ваше python-приложение с помощью runC, не используя docker или containerd.
Предоставьте скриншоты действий .